<template>
  <div aria-hidden="true">
    <div class="flex items-center justify-start">
      <div
        class="border-[1px] border-solid border-[#d9d9d9] rounded-[4px] relative image-wrap overflow-hidden mr-[10px]"
        :style="style" v-if="imagesList.data.length" v-for="(item, index) in imagesList.data" :key="index">
        <div class="w-full h-full flex items-center justify-center">
          <a-image :width="100" :preview="false" :src="imgUrl(item)" />
        </div>
        <div
          class="absolute w-full h-full flex items-center justify-center cursor-pointer inset-0 bg-[#000000] bg-opacity-60">
          <ZoomInOutlined class="text-[18px] mr-[8px] text-[#ffffff]" @click="openPreview" />
          <DeleteOutlined class="text-[18px] text-[#ffffff]" @click.stop="deleteImage(index)" />
        </div>
      </div>
      <div class="border-[1px] border-solid border-[#d9d9d9] rounded-[4px] relative overflow-hidden" :style="style"
        v-if="isShowAddBtn">
        <div class="w-full h-full flex flex-col items-center justify-center cursor-pointer" @click="openModal">
          <PlusOutlined class="font-[18px]" />
          {{ imageText }}
        </div>
      </div>
    </div>
    <div style="display: none">
      <a-image-preview-group :preview="{ visible, onVisibleChange: (vis: boolean) => (visible = vis) }">
        <a-image v-for="(item, index) in imagesList.data" :key="index" :src="imgUrl(item)" />
      </a-image-preview-group>
    </div>

    <a-modal v-model:open="open" :bodyStyle="{ padding: 0 }" :width="isMiniScreen ? 'auto' : '900px'" title="图片库"
      @ok="onSubmit">
      <div class="flex border-0 border-t-[1px] border-b-[1px] border-solid border-[#f2f2f2]">
        <div class="w-[140px] flex flex-col justify-between mb-[10px] mr-[10px] <lg:hidden">
          <div class="py-[20px]" v-if="!groupData.loading">
            <div @click="changeGroup(0)"
              class="py-6px rounded-[4px] cursor-pointer pl-[20px] my-[2px] text-sm hover:(text-[#333333] bg-[#f2f6fc])"
              :class="[formState.group_id == 0 ? 'text-[#333333] bg-[#f2f6fc]' : '']">
              全部
            </div>
            <div @click="changeGroup(item.group_id)"
              class="py-6px rounded-[4px] cursor-pointer pl-[20px] my-[2px] text-sm hover:(text-[#333333] bg-[#f2f6fc])"
              :class="[item.group_id == formState.group_id ? 'text-[#333333] bg-[#f2f6fc]' : '']"
              v-for="(item, index) in groupData.data" :key="index">
              {{ item.group_name }}
            </div>
          </div>
          <div v-else class="py-[20px] flex items-center justify-center">
            <a-spin />
          </div>
          <a-popconfirm ok-text="确定" :icon="false" cancel-text="取消" @confirm="addGroupconfirm">
            <template #title>
              <a-input v-model:value="formGroup.group_name" placeholder="请输入分组名称" show-count :maxlength="10" />
            </template>
            <div
              class="w-full text-center py-[5px] text-sm border-[1px] border-solid border-[#d9d9d9] rounded-[2px] ml-auto cursor-pointer">
              添加分组
            </div>
          </a-popconfirm>

        </div>
        <div
          class="flex-1 border-0 border-l-[1px] <lg:border-r-[1px] border-solid border-[#f2f2f2] pl-[10px] pt-[10px]">
          <div class="flex items-center justify-between mb-[10px]">
            <a-form-item-rest>
              <a-upload accept=".jpg,.png,.jpeg,.webp,.gif" list-type="picture" v-model:file-list="fileList"
                :headers="headers" name="iFile" :show-upload-list="false" :multiple="true" :max-count="10"
                :action="uploadImageApi" :before-upload="beforeUpload" @change="handleChange">
                <a-button type="primary" :loading="btnLoading">上传</a-button>
              </a-upload>
            </a-form-item-rest>
            <a-form-item-rest>
              <a-input-search v-model:value="formState.keyword" enter-button allowClear placeholder="请输入图片名称"
                class="w-[200px]" @search="onSearch" />
            </a-form-item-rest>
          </div>
          <div class="flex-1 flex flex-col justify-between" v-if="attachment.data.length > 0">
            <div class="flex items-start flex-wrap content-start h-[450px] overflow-y-auto">
              <div class="mb-[10px] mr-[10px]" v-for="(item, index) in attachment.data" :key="index">
                <div @click="selectFile(item)"
                  class="relative flex items-center justify-center cursor-pointer bg-[#f2f6fc] rounded-[4px] overflow-hidden">
                  <!-- <a-image :width="100" :preview="false" :src="item.url" /> -->
                  <img class="w-[100px] h-[100px] object-contain" :src="imgUrl(item.url)" :alt="item.real_name">
                  <div v-if="selectedFileIndex.includes(item.file_id)"
                    class="absolute w-full h-full flex items-center justify-center cursor-pointer inset-0 bg-[#000000] bg-opacity-60">
                    <CheckOutlined class="text-[#ffffff] text-[40px] font-bold" />
                  </div>
                </div>
                <div
                  class="text-sm text-[#333333] w-[100px] mt-[4px] mb-[10px] overflow-hidden overflow-ellipsis whitespace-nowrap text-center">
                  {{ item.real_name }}
                </div>
              </div>
            </div>
            <div class="mt-auto py-[10px] flex justify-end">
              <a-pagination v-model:current="formState.current_page" v-model:pageSize="formState.per_page"
                :total="formState.total" show-less-items @change="onSearch" />
            </div>
          </div>
          <div v-else class="py-[100px] h-[502px]">
            <a-empty />
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>
<script lang="ts" setup>
import { ref, computed, reactive, toRaw, onMounted, watch } from 'vue';
import { message } from 'ant-design-vue';
import { ZoomInOutlined, DeleteOutlined, PlusOutlined, CheckOutlined } from '@ant-design/icons-vue';
import type { UploadChangeParam, UploadProps } from 'ant-design-vue';
import useUserStore from '@/stores/user';
import { addFileGroup, fileGroupList, uploadImageApi, getFileList } from '@/utils/api/file';
import { imgUrl } from '@/utils/libs/common';

const userStore = useUserStore();

const prop = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  // 多选模式, 默认单选
  multiple: {
    type: Boolean,
    default: false,
  },
  width: {
    type: String,
    default: '100px'
  },
  height: {
    type: String,
    default: '100px'
  },
  imageText: {
    type: String,
    default: '上传'
  },
  maxNum: {
    type: Number,
    default: 10
  },
})

const emit = defineEmits(['update:modelValue', 'change'])

const value = computed({
  get: () => prop.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const imagesList = reactive({
  data: [] as any[]
})

const setValue = () => {
  value.value = toRaw(imagesList.data).toString()
}


watch(() => prop.modelValue, () => {
  if (value.value.indexOf('data:image') != -1) {
    imagesList.data = [value.value]
  } else {
    imagesList.data = [
      ...value.value.split(',').filter((item: string) => {
        return item
      })
    ]
  }
  setValue()
}, { immediate: true })

const isMiniScreen = window.innerWidth > 1000 ? false : true;

//筛选条件
const formState = reactive({
  group_id: 0,
  keyword: '',
  current_page: 1,
  last_page: 0,
  per_page: 18,
  total: 0,
});

const attachment: Record<string, any> = reactive({
  loading: true,
  data: []
});

// 搜索框
const onSearch = () => {
  getFileList({
    group_id: formState.group_id,
    file_type: formGroup.type,
    keyword: formState.keyword,
    page: formState.current_page,
    per_page: formState.per_page
  }).then((res: any) => {
    formState.current_page = res.data.current_page;
    formState.last_page = res.data.last_page;
    formState.per_page = res.data.per_page;
    formState.total = res.data.total;
    attachment.data = res.data.data;
  })
};

// 切换分组
const changeGroup = (group_id: number) => {
  formState.group_id = group_id;
  onSearch();
};

// 添加分组的模型
const formGroup = reactive({
  type: 'image',
  group_name: '',
  sort: 100
});

// 分组列表
const groupData = reactive({
  data: [] as any[],
  loading: true,
});

/**
 * 确认创建分组
 */
const addGroupconfirm = () => {
  if (formGroup.group_name == '') {
    message.error('分组名称不能为空')
    return
  }
  addFileGroup(formGroup).then((res: any) => {
    formGroup.group_name = ''
    message.success(res.message);
    refreshGroupList();
  })
};

// 刷新分组列表
const refreshGroupList = () => {
  fileGroupList({ type: formGroup.type }).then((res: any) => {
    groupData.data = res.data;
    groupData.loading = false;
  }).catch(() => {
    groupData.loading = false;
  })
}

//上传列表
const fileList = ref<UploadProps['fileList']>([]);

// 上传文件头
const headers = ref({
  Authorization: 'Bearer ' + userStore.token,
});

const btnLoading = ref(false);

const beforeUpload = (file: any) => {
  const isJpgOrPngOrWebp =
    file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/webp' || file.type === 'image/gif';
  if (!isJpgOrPngOrWebp) {
    message.error('文件格式不正确!');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('图片最大限制2MB!');
  }
  btnLoading.value = true;
  return isJpgOrPngOrWebp && isLt2M;
};

const handleChange = (info: UploadChangeParam) => {
  if (info.file.status !== 'uploading') {
    // console.log(info.file, info.fileList);
  }
  if (info.file.status === 'done') {

    message.success(`${info.file.name} ${info.file.response.message}`);
  } else if (info.file.status === 'error') {
    message.error(`${info.file.name} ${info.file.response.message}`);
  }
  if (info.fileList.every(f => f.status === 'done')) {
    console.log('全部上传完成')
    onSearch();
  }
  btnLoading.value = false;
};

// 选中的文件
const selectedFile: Record<string, any> = reactive({})

const selectedFileIndex: any = reactive([])

/**
 * 选择文件
 */
const selectFile = (data: any) => {
  if (selectedFile[data.file_id]) {
    delete selectedFile[data.file_id]
    selectedFileIndex.splice(selectedFileIndex.indexOf(data.file_id), 1);
  } else {
    const keys = Object.keys(toRaw(selectedFile))
    const length = keys.length + imagesList.data.length;// 总选择数量

    if (!prop.multiple && length > 0) {
      delete selectedFile[keys[0]]
      selectedFileIndex.splice(selectedFileIndex.indexOf(keys[0]), 1);
    } else if (length >= prop.maxNum) {
      message.warning('限制最多' + prop.maxNum + '张');
      return
    }
    selectedFile[data.file_id] = toRaw(data)
    selectedFileIndex.push(data.file_id);
  }
}

onMounted(() => {
  refreshGroupList();
  onSearch();
})

//判断是否显示上传按钮
const isShowAddBtn = computed(() => {
  if (prop.multiple) {
    return imagesList.data.length < prop.maxNum ? true : false;
  } else {
    return imagesList.data.length == 0 ? true : false;
  }
})

// 删除图片
const deleteImage = (index: any) => {
  imagesList.data.splice(index, 1)
  selectedFileIndex.splice(0);
  setValue();
}


const open = ref<boolean>(false);

watch(() => open.value, () => {
  if (open.value) {
    // 清空Record类型的对象
    for (const key in selectedFile) {
      if (Object.prototype.hasOwnProperty.call(selectedFile, key)) {
        delete selectedFile[key];
      }
    }
    selectedFileIndex.splice(0);
  }
}, { immediate: true })

// 打开弹窗
const openModal = () => {
  open.value = true;
};



// 确认选择图片
const onSubmit = (e: MouseEvent) => {
  Object.keys(selectedFile).forEach(key => {
    imagesList.data.push(selectedFile[key].url)
  });

  setValue();
  open.value = false;
};

// 图片预览
const visible = ref(false);

const openPreview = () => {
  console.log(444444)
  visible.value = true;
}

// 动态图片选取样式
const style = computed(() => {
  return {
    width: prop.width,
    height: prop.height
  }
})

</script>